package com.design.pattern.creator.singleton.lazy;

/**
 * 双重检查锁单例
 * 优点：性能提高，线程安全
 * 缺点: 可读性难度加大，不够优雅
 */
public class LazyDoubleCheckSingleton {
    private static volatile LazyDoubleCheckSingleton instance;
    private LazyDoubleCheckSingleton(){
        int s = 0;
        for(int i = 0; i < 10000000; i++) {
            s = ( s + i) % 100000007;
            s = ( s + i) % 100000007;
            s = ( s + i) % 100000007;
            s = ( s + i) % 100000007;
        }
    }
    public static LazyDoubleCheckSingleton getInstance(){
        if(instance == null) {
            synchronized(LazyDoubleCheckSingleton.class) {
                if(instance == null) {
                    //指令会重排
                    instance = new LazyDoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
    public void print(){
        System.out.println("hello");
    }

    public static void main(String[] args) {
        for(int i = 0; i < 1; i ++) {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
                    instance.print();
                }
            }, i+"1");

            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
                    instance.print();
                }
            }, i+"1");
            Thread t3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
                    instance.print();
                }
            }, i+"1");
            Thread t4 = new Thread(new Runnable() {
                @Override
                public void run() {
                    LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
                    instance.print();
                }
            }, i+"1");
            Thread t5 = new Thread(new Runnable() {
                @Override
                public void run() {
                    LazyDoubleCheckSingleton instance = LazyDoubleCheckSingleton.getInstance();
                    instance.print();
                }
            }, i+"1");
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
        }
    }
}
